/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package Wires.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.m2m.atl.engine.vm.nativelib.ASMOclAny;

import Wires.BasicData;
import Wires.CompositeTransformation;
import Wires.ConnectableElement;
import Wires.IdentityTransformation;
import Wires.InputFormalParameter;
import Wires.OutputActualParameter;
import Wires.Query;
import Wires.WiresPackage;
import Wires.exep.ResourceNotFoundException;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Basic Data</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link Wires.impl.BasicDataImpl#getPath <em>Path</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class BasicDataImpl extends TypedElementImpl implements BasicData {
	
	/***************************************************/
	/***************** Modifications *******************/
	
	ASMOclAny value;
	
	public ASMOclAny getValue(){
		return value;
	}
	
	public void execute(ConnectableElement incoming) throws Exception{
		
		if (incoming instanceof BasicData){	
			//Copy the basic data file			
			String inPath = ((BasicDataImpl) incoming).getPath();						
			String outPath = ((BasicDataImpl) this).getPath();
			
			File in = null;
			try {
				in = new File(inPath);
			} catch (Exception e) {
				throw new ResourceNotFoundException(incoming);
			}
			
			File out = null;
			try {
				out = new File (outPath);
			} catch (Exception e) {
				throw new ResourceNotFoundException(this);
			}
			
			copy(in,out);			
		}else if (incoming instanceof OutputActualParameter){		
			//BasicData from Query OutputParameter
			if (((OutputActualParameter) incoming).eContainer() instanceof Query ||
					((OutputActualParameter) incoming).eContainer() instanceof CompositeTransformation ||
					((OutputActualParameter) incoming).eContainer() instanceof IdentityTransformation){
				this.value = ((OutputActualParameterImpl)incoming).getBasicDataValue();
				if (((OutputActualParameterImpl)incoming).eContainer() instanceof Model2TextTransformationImpl){
					// Remove simple Quote (') at the beginning and the end
					writeValueToFile(this.value.toString().substring(1,this.value.toString().length()-1), this.getPath());
				}else{
					writeValueToFile(this.value.toString(), this.getPath());
				}
			}else if (incoming instanceof InputFormalParameter){
				this.value = ((InputFormalParameterImpl)incoming).getBasicDataValue();
				if (((InputFormalParameterImpl)incoming).eContainer() instanceof Model2TextTransformationImpl){
					// Remove simple Quote (') at the beginning and the end
					writeValueToFile(this.value.toString().substring(1,this.value.toString().length()-1), this.getPath());
				}else{
					writeValueToFile(this.value.toString(), this.getPath());
				}
			}
		}
 	}	
	
	protected static void writeValueToFile(String value, String path) throws Exception{
		FileWriter out = new FileWriter(path);
		BufferedWriter bw = new BufferedWriter(out);
		bw.write(value);
		bw.close();
		out.close();
	}
	
	private void copy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);
                
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }
	
	/**************** Modifications End ****************/
	/***************************************************/
	
	/**
	 * The default value of the '{@link #getPath() <em>Path</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPath()
	 * @generated
	 * @ordered
	 */
	protected static final String PATH_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getPath() <em>Path</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPath()
	 * @generated
	 * @ordered
	 */
	protected String path = PATH_EDEFAULT;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected BasicDataImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return WiresPackage.Literals.BASIC_DATA;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getPath() {
		return path;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPath(String newPath) {
		String oldPath = path;
		path = newPath;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, WiresPackage.BASIC_DATA__PATH, oldPath, path));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case WiresPackage.BASIC_DATA__PATH:
				return getPath();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case WiresPackage.BASIC_DATA__PATH:
				setPath((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case WiresPackage.BASIC_DATA__PATH:
				setPath(PATH_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case WiresPackage.BASIC_DATA__PATH:
				return PATH_EDEFAULT == null ? path != null : !PATH_EDEFAULT.equals(path);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (path: ");
		result.append(path);
		result.append(')');
		return result.toString();
	}

} //BasicDataImpl
